# -*- Mode: python; coding: utf-8; tab-width: 4; indent-tabs-mode: s; -*- 
#
# Copyright (C) 2008 - Grzes Furga
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.


import os
import rhythmdb
import gnomevfs
import rb
import gobject
import time

import gtk              
import gtk.gtkgl        

from OpenGL.GL import *
from OpenGL.GLU import *


from flow_engine import CoverFlowEngine

import sys
def deb(s):
    sys.stderr.write(s)

class CoverFlowWidget(gtk.DrawingArea, gtk.gtkgl.Widget):
    """Custom OpenGL Widget displaying an opengl Atlas viewer and catching Gtk events.
    The Gtk mouse events are translated into camera commands for the viewer."""
    
    def __init__(self):
        gtk.DrawingArea.__init__(self)    # Calls gtk.DrawingArea initializer
        display_mode = (gtk.gdkgl.MODE_RGB | gtk.gdkgl.MODE_DOUBLE | gtk.gdkgl.MODE_DEPTH )
        self.width, self.height = 1,1
        try:               
            glconfig = gtk.gdkgl.Config(mode=display_mode)
        except gtk.gdkgl.NoMatches:
            display_mode &= ~gtk.gdkgl.MODE_SINGLE
            glconfig = gtk.gdkgl.Config(mode = display_mode) 
        self.set_gl_capability(glconfig)
        self.set_events(gtk.gdk.BUTTON_MOTION_MASK | gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK|
            gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_RELEASE_MASK|
            gtk.gdk.BUTTON_PRESS_MASK |  gtk.gdk.SCROLL_MASK)   

                
        self.connect( "expose_event", self.on_expose_event )
        self.connect( "realize", self.on_realize )
        self.connect( "configure_event", self.on_configure_event )
        
        self.connect ('size-request', self.size_request)
		 
        
        #self.connect( "motion-notify-event", self.on_mouse_motion )
        #self.connect( "button-press-event", self.on_button_press )
        self.connect( "button-release-event", self.on_button_release )
        
        self.engine = None
        
        self._drag = 0
        self._dx, self._dy = 0,0
               
        
        #self.connect( "motion-notify-event", self.on_mouse_motion )
        #self.connect( "button-press-event", self.on_button_press )
        self.connect( "button-release-event", self.on_button_release )
        
        self.engine = None
    
    def __del__(self):
        self.engine = None 
          
    def size_request (self, widget, requisition):
        requisition.width, requisition.height = -1, 200

    def load_covers(self, songs):
        self.engine.load_covers(songs)
        self.queue_draw()

    def goto(self, entry_id):
        self.engine.goto(entry_id)
        gobject.idle_add(self.queue_draw_event)
    
           
    def on_button_release(self, widget, event):
        if event.button == 3:
            self.toggle_light() # hack until a proper menu comes along        pass
        else:
            deb("where: %f, %f\n" % (float(event.x) / self.width, (( float(event.x) / self.width )-0.5 )))
        
    # graphics calls:
    def toggle_light(self):
        gldrawable = self.get_gl_drawable()
        glcontext = self.get_gl_context()
        gldrawable.gl_begin(glcontext)     
         
        self.engine.toggle_light() 
        self.engine.glstate_setup()

        gldrawable.gl_end()
        self.queue_draw()
        
    def on_configure_event(self, widget, event):
        self.width, self.height = event.width, event.height
        gldrawable = self.get_gl_drawable()
        glcontext = self.get_gl_context()
        gldrawable.gl_begin(glcontext)     
         
        if not self.engine:
            self.engine = CoverFlowEngine()

        self.engine.glstate_setup()
        self.engine.projection_setup(self.width, self.height)
                
        gldrawable.gl_end()
        
    
    def on_realize(self,*args):
        """ """
        gldrawable = self.get_gl_drawable()    
        glcontext = self.get_gl_context()      

        if not gldrawable.gl_begin(glcontext):
            return
        
        if not self.engine:
            self.engine = CoverFlowEngine()
            
        gldrawable.gl_end()


    # drawing callbacks
    # calling draw as often as possible, only when there's sth to draw   
    def queue_draw_event(self): 
        
        self.queue_draw()      
        return self.engine.animate

    def on_expose_event(self, *args):
        gldrawable = self.get_gl_drawable()
        glcontext  = self.get_gl_context()
        gldrawable.gl_begin(glcontext)
        
        self.engine.draw()
            
        
        gldrawable.swap_buffers()
        gldrawable.gl_end() 



        

        
